const User = require("../model/user.model");

class UserService {
  /**
   * 操作数据库是异步的
   * 这里使用async和await处理异步，await需要和async配套使用。
   * async的作用是将async函数的返回值封装成promise对象。
   * 若async函数里没有await，执行起来等同于普通函数。
   */
  async createUser(user_name, password) {
    /**
     * 插入数据（数据库操作是异步的，返回 Promise）
     * await 的执行逻辑：
     * 1. 右侧表达式若为 Promise，等待其状态变为 resolved/rejected；
     *    若不是 Promise，会被包装为一个已 resolved 的 Promise（如 await 123 等价于 await Promise.resolve(123)）。
     * 2. 暂停当前 async 函数的执行，将后续代码（await 之后的代码）放入微任务队列。
     * 3. 先执行当前事件循环中剩余的同步代码，再执行微任务队列中的代码。
     * 4. 最后恢复 async 函数的执行，继续处理 await 之后的逻辑。
     */
    const res = await User.create({
      // 属性名对应表的字段: 属性值对应传递过来的数据
      user_name,
      password,
    });
    return res.dataValues;
  }

  /**
   * 获取用户信息
   * @param {*} param0 { id, user_name, password, is_admin }
   * @returns
   */
  async getUserInfo({ id, user_name, password, is_admin }) {
    const whereOpt = {};
    // 若参数存在，则存到whereOpt对象里
    id && Object.assign(whereOpt, { id });
    user_name && Object.assign(whereOpt, { user_name });
    password && Object.assign(whereOpt, { password });
    is_admin && Object.assign(whereOpt, { is_admin });
    // 查询单条满足条件的记录
    const res = await User.findOne({
      attributes: ["id", "user_name", "password", "is_admin"], // 告诉数据库“找到记录后，要返回该记录的哪些字段”。只查询需要的字段，可以减少数据传输，优化性能（不设置时查询所有字段）
      where: whereOpt, // 查询条件
    });
    // 若能查询到结果返回查询结果，没查询到则返回null
    return res ? res.dataValues : null;
  }

  /**
   * 通过id更新用户信息
   * @param {*} param0 参数。（传对象的原因：让代码可以复用，不用固定属性的顺序，如果不是对象，某个属性不传就不好处理了）
   */
  async updateById({ id, user_name, password, is_admin }) {
    // 更新条件
    const whereOpt = { id };
    // 要更新的值
    const newUser = {};
    // 若参数存在，则存到newUser对象里
    user_name && Object.assign(newUser, { user_name });
    password && Object.assign(newUser, { password });
    is_admin && Object.assign(newUser, { is_admin });
    // 调用User模型的update方法来更新数据
    const res = await User.update(newUser, { where: whereOpt });
    // console.log("res", res);
    return res[0] > 0 ? true : false;
  }
}

module.exports = new UserService();
